package com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.OrgUserStuUtil;
import com.xyht.sca_s.student_manage_system.modules.common.constant.TaskNameExample;
import com.xyht.sca_s.student_manage_system.modules.common.constant.TaskTypeConstant;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTask;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTaskDetail;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskMapper;
import com.xyht.sca_s.student_manage_system.modules.org.constants.UpdateTypeConstant;
import com.xyht.sca_s.student_manage_system.modules.signUp.constant.SmsSignUpCommonConstant;
import com.xyht.sca_s.student_manage_system.modules.student.entity.SmsStudentInfo;
import com.xyht.sca_s.student_manage_system.modules.student.mapper.SmsStudentInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.SmsWnsBookFeesPlan;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.SmsWnsBookFeesPlanFeesRecord;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.req.*;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.resp.SmsWnsBookFeesPlanFeesRecordResp;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.mapper.SmsWnsBookFeesPlanFeesRecordMapper;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.mapper.SmsWnsBookFeesPlanMapper;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.service.SmsWnsBookFeesPlanFeesRecordService;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.util.AssistantUtil;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskDetailReason.*;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.*;
import static com.xyht.sca_s.student_manage_system.modules.signUp.constant.SmsSignUpCommonConstant.PER_SHEET_NUM;

/**
 * <p>
 * 学生书杂费记录表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-04-08
 */
@Service
public class SmsWnsBookFeesPlanFeesRecordServiceImpl extends ServiceImpl<SmsWnsBookFeesPlanFeesRecordMapper, SmsWnsBookFeesPlanFeesRecord> implements SmsWnsBookFeesPlanFeesRecordService {

    @Resource
    private OrgUserStuUtil orgUserStuUtil;
    @Resource
    private SmsImportTaskMapper smsImportTaskMapper;
    @Resource
    private PlatformTransactionManager platformTransactionManager;
    @Resource
    private SmsStudentInfoMapper smsStudentInfoMapper;
    @Resource
    private SmsImportTaskDetailMapper smsImportTaskDetailMapper;
    @Resource
    private SmsWnsBookFeesPlanMapper smsWnsBookFeesPlanMapper;
    @Resource
    private AssistantUtil assistantUtil;

    @Override
    public ResponseResult addRecord(SmsWnsBookFeesPlanFeesRecordReq req) {
        if (isNullOrEmpty(req.getUserId(), req.getPlanId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        String stuId = orgUserStuUtil.getStuIdByUserId(req.getUserId());

        SmsWnsBookFeesPlanFeesRecord record = new SmsWnsBookFeesPlanFeesRecord();
        BeanUtils.copyProperties(req, record, "needBackAmount");
        record.setStuId(stuId);
        record.setIsBack(false); // 默认未退

        // 实付金额
        BigDecimal paymentAmount = BigDecimal.ZERO;
        if (req.getPaymentAmount() != null) {
            paymentAmount = req.getPaymentAmount();
        }

        // 应缴金额
        BigDecimal totalAmount = BigDecimal.ZERO;
        if (req.getTotalAmount() != null) {
            totalAmount = req.getTotalAmount();
        }

        // 设置实付金额和应缴金额
        record.setPaymentAmount(paymentAmount);
        record.setTotalAmount(totalAmount);

        // 计算应退金额(实付金额 - 应缴金额)
        record.setNeedBackAmount(paymentAmount.subtract(totalAmount));

        this.save(record);

        return CommonResult.success(record.getId());
    }

    @Override
    @Transactional
    public ResponseResult delRecord(SmsWnsIdListReq req) {
        List<String> idList = req.getIdList();
        if (idList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        this.removeByIds(idList);

        return CommonResult.success();
    }

    @Override
    public ResponseResult updateRecord(SmsWnsBookFeesPlanFeesRecordReq req) {
        if (isNullOrEmpty(req.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        // 校验书杂费计划是否存在
        SmsWnsBookFeesPlanFeesRecord record = this.getById(req.getId());
        if (record == null) {
            return CommonResult.failed(CommonCodeEnum.WNS_STUDENT_BOOK_FEES_PLAN_NOT_EXIST);
        }

        // 记录应退金额
        BigDecimal needBackAmount = record.getNeedBackAmount();
        // 根据实付计算应退金额
        if (req.getPaymentAmount() != null) {
            // 计算实付差值
            BigDecimal subtract = req.getPaymentAmount().subtract(record.getPaymentAmount());
            needBackAmount = needBackAmount.add(subtract);
        }

        // 根据应缴计算应退金额
        if (req.getTotalAmount() != null) {
            // 计算应缴差值
            BigDecimal subtract = req.getTotalAmount().subtract(record.getTotalAmount());
            needBackAmount = needBackAmount.subtract(subtract);
        }

        BeanUtils.copyProperties(req, record, "needBackAmount");
        // 设置应退金额
        record.setNeedBackAmount(needBackAmount);
        if (!isNullOrEmpty(req.getDescription())) {
            record.setDescription(req.getDescription());
        }

        this.updateById(record);

        return CommonResult.success();
    }

    @Override
    public ResponseResult listRecord(Integer pageNum, Integer pageSize, String planId, Boolean isBack, String searchStr) {
        LambdaQueryWrapper<SmsWnsBookFeesPlanFeesRecord> queryWrapper = new LambdaQueryWrapper<SmsWnsBookFeesPlanFeesRecord>()
                .orderByDesc(SmsWnsBookFeesPlanFeesRecord::getCreateTime);

        if (!isNullOrEmpty(planId)) {
            queryWrapper.eq(SmsWnsBookFeesPlanFeesRecord::getPlanId, planId);
        }

        if (isBack != null) {
            queryWrapper.eq(SmsWnsBookFeesPlanFeesRecord::getIsBack, isBack);
        }

        if (!isNullOrEmpty(searchStr)) {
            List<String> stuIdList = orgUserStuUtil.getStuIdListBySearchStr(searchStr);
            queryWrapper.in(SmsWnsBookFeesPlanFeesRecord::getStuId, stuIdList.isEmpty() ? Collections.singletonList("") : stuIdList);
        }

        // 分页查询
        Page<SmsWnsBookFeesPlanFeesRecord> page = new Page<>(pageNum, pageSize);
        this.page(page, queryWrapper);
        List<SmsWnsBookFeesPlanFeesRecordResp> collect = page.getRecords().stream().map(bookFeesPlan -> {
            SmsWnsBookFeesPlanFeesRecordResp planResp = new SmsWnsBookFeesPlanFeesRecordResp();
            BeanUtils.copyProperties(bookFeesPlan, planResp);

            // 设置学生信息
            SmsStudentInfo studentInfo = smsStudentInfoMapper.selectById(bookFeesPlan.getStuId());
            if (studentInfo != null) {
                planResp.setStudentInfo(studentInfo);
            }

            return planResp;
        }).collect(Collectors.toList());

        return CommonResult.success(collect, (int) page.getTotal());
    }

    @Override
    @Async
    public Future<ResponseResult> feesRecordBatchAdd(FeesRecordBatchAddReq req, String userId) {
        // 1. 校验参数
        if (isNullOrEmpty(req.getType(), req.getRecordAddReqList())) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        // 2. 创建导入任务
        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setTaskName(TaskNameExample.TASK_NAME_STUDENT_FEES_IMPORT);
        smsImportTask.setUserId(userId);
        smsImportTask.setStatus(TASK_STATUS_DOING); // 任务状态 0:进行中
        smsImportTask.setTaskType(TaskTypeConstant.TASK_TYPE_STUDENT_FEES_PLAN_FEES_RECORD_IMPORT);
        smsImportTaskMapper.insert(smsImportTask);
        String taskId = smsImportTask.getId();
        if (isNullOrEmpty(taskId)) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        // 3. 获取导入数据循环导入
        List<FeesRecordAddReq> recordAddReqList = req.getRecordAddReqList();
        int OFFSET_ROW = 1; // 初始化行数
        int taskStatus = TASK_STATUS_DONE; // 任务状态: 完成
        for (int i = 0; i < recordAddReqList.size(); i++) {
            // 3.1 开启事务
            DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
            // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
            dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 设置嵌套事务
            TransactionStatus status = platformTransactionManager.getTransaction(dt);
            try {
                // 3.2 获取本条导入数据
                FeesRecordAddReq recordAddReq = recordAddReqList.get(i);

                // 3.3 校验参数并获取导入信息
                // 必填字段验证(学生学号/身份证号/手机号、姓名、计划名)
                if (isNullOrEmpty(recordAddReq.getStuNo(), recordAddReq.getName(), recordAddReq.getPlanName())) {
                    platformTransactionManager.rollback(status);
                    createImportTaskDetail(isNullOrEmpty(recordAddReq.getStuNo()) ? "" : recordAddReq.getStuNo(), isNullOrEmpty(recordAddReq.getName()) ? "" : recordAddReq.getName(), taskId, REASON_INVALID_PARAM, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }

                // 校验计划是否存在
                SmsWnsBookFeesPlan smsWnsBookFeesPlan = smsWnsBookFeesPlanMapper.selectOne(new LambdaQueryWrapper<SmsWnsBookFeesPlan>()
                        .eq(SmsWnsBookFeesPlan::getName, recordAddReq.getPlanName()));
                if (smsWnsBookFeesPlan == null) {
                    platformTransactionManager.rollback(status);
                    createImportTaskDetail(recordAddReq.getStuNo(), recordAddReq.getName(), taskId, REASON_STUDENT_FEES_PLAN_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }

                // 根据身份证号或手机号或学号匹配学生
                List<SmsStudentInfo> studentInfoList = smsStudentInfoMapper.selectList(new LambdaQueryWrapper<SmsStudentInfo>()
                        .eq(SmsStudentInfo::getStuName, recordAddReq.getName())
                        .and(wrapper -> wrapper.eq(SmsStudentInfo::getStuIdCard, recordAddReq.getStuNo()).or() // 身份证号
                                .eq(SmsStudentInfo::getStuTel, recordAddReq.getStuNo()).or() // 手机号
                                .eq(SmsStudentInfo::getStuNo, recordAddReq.getStuNo()))); // 学号
                if (studentInfoList.size() != 1) { // 学籍信息不存在
                    platformTransactionManager.rollback(status);
                    createImportTaskDetail(recordAddReq.getStuNo(), recordAddReq.getName(), taskId, REASON_STUDENT_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }
                SmsStudentInfo studentInfo = studentInfoList.get(0);

                // 3.4 根据添加类型添数据
                switch (req.getType()) {
                    case UpdateTypeConstant.UPDATE_TYPE_UPDATE_ADD: // 3.4.1 更新添加
                        // 3.4.1.1 查询是否存在记录
                        SmsWnsBookFeesPlanFeesRecord record = this.getOne(new LambdaQueryWrapper<SmsWnsBookFeesPlanFeesRecord>()
                                .eq(SmsWnsBookFeesPlanFeesRecord::getStuId, studentInfo.getId())
                                .eq(SmsWnsBookFeesPlanFeesRecord::getPlanId, smsWnsBookFeesPlan.getId()));

                        // 3.4.1.2 添加数据
                        if (record != null) { // 存在记录进行修改
                            // 记录应退金额
                            BigDecimal needBackAmount = record.getNeedBackAmount();
                            // 根据实付计算应退金额
                            if (recordAddReq.getPaymentAmount() != null) {
                                // 计算实付差值
                                BigDecimal subtract = recordAddReq.getPaymentAmount().subtract(record.getPaymentAmount());
                                needBackAmount = needBackAmount.add(subtract);

                                // 设置实付金额
                                record.setPaymentAmount(recordAddReq.getPaymentAmount());
                            }

                            // 根据应缴计算应退金额
                            if (recordAddReq.getTotalAmount() != null) {
                                // 计算应缴差值
                                BigDecimal subtract = recordAddReq.getTotalAmount().subtract(record.getTotalAmount());
                                needBackAmount = needBackAmount.subtract(subtract);

                                // 设置应缴金额
                                record.setTotalAmount(recordAddReq.getTotalAmount());
                            }

                            // 设置应退金额
                            record.setNeedBackAmount(needBackAmount);

                            // 设置备注
                            if (isNullOrEmpty(recordAddReq.getDescription())) {
                                record.setDescription(recordAddReq.getDescription());
                            }

                            // 修改记录
                            this.updateById(record);
                        } else { // 不存在记录进行新增
                            SmsWnsBookFeesPlanFeesRecord newRecord = new SmsWnsBookFeesPlanFeesRecord();
                            String stuUserId = orgUserStuUtil.getUserIdByStuId(studentInfo.getId());
                            if (stuUserId == null) {
                                platformTransactionManager.rollback(status);
                                createImportTaskDetail(recordAddReq.getStuNo(), recordAddReq.getName(), taskId, REASON_STUDENT_USER_ID_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                                taskStatus = TASK_STATUS_ERR;
                                continue;
                            }
                            newRecord.setPlanId(smsWnsBookFeesPlan.getId());
                            newRecord.setUserId(stuUserId);
                            newRecord.setStuId(studentInfo.getId());

                            // 获取实付金额
                            BigDecimal paymentAmount = BigDecimal.ZERO;
                            if (recordAddReq.getPaymentAmount() != null) {
                                paymentAmount = recordAddReq.getPaymentAmount();
                            }
                            // 获取应缴金额
                            BigDecimal totalAmount = BigDecimal.ZERO;
                            if (recordAddReq.getTotalAmount() != null) {
                                totalAmount = recordAddReq.getTotalAmount();
                            }
                            // 设置实付金额和应缴金额
                            newRecord.setPaymentAmount(paymentAmount);
                            newRecord.setTotalAmount(totalAmount);

                            // 计算应退金额(实付金额 - 应缴金额)
                            newRecord.setNeedBackAmount(paymentAmount.subtract(totalAmount));

                            // 设置是否已退
                            newRecord.setIsBack(false); // 默认未退

                            // 设置备注
                            if (isNullOrEmpty(recordAddReq.getDescription())) {
                                newRecord.setDescription(recordAddReq.getDescription());
                            }

                            // 保存记录
                            this.save(newRecord);
                        }

                        break;
                    case UpdateTypeConstant.UPDATE_TYPE_COVER_ADD: // 3.4.2 覆盖添加
                        // 3.4.2.1 删除原有数据
                        this.remove(new LambdaQueryWrapper<SmsWnsBookFeesPlanFeesRecord>()
                                .eq(SmsWnsBookFeesPlanFeesRecord::getStuId, studentInfo.getId())
                                .eq(SmsWnsBookFeesPlanFeesRecord::getPlanId, smsWnsBookFeesPlan.getId()));

                        // 3.4.2.2 添加数据
                        SmsWnsBookFeesPlanFeesRecord newRecord = new SmsWnsBookFeesPlanFeesRecord();
                        String stuUserId = orgUserStuUtil.getUserIdByStuId(studentInfo.getId());
                        if (stuUserId == null) {
                            platformTransactionManager.rollback(status);
                            createImportTaskDetail(recordAddReq.getStuNo(), recordAddReq.getName(), taskId, REASON_STUDENT_USER_ID_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                            taskStatus = TASK_STATUS_ERR;
                            continue;
                        }
                        newRecord.setPlanId(smsWnsBookFeesPlan.getId());
                        newRecord.setUserId(stuUserId);
                        newRecord.setStuId(studentInfo.getId());

                        // 获取实付金额
                        BigDecimal paymentAmount = BigDecimal.ZERO;
                        if (recordAddReq.getPaymentAmount() != null) {
                            paymentAmount = recordAddReq.getPaymentAmount();
                        }
                        // 获取应缴金额
                        BigDecimal totalAmount = BigDecimal.ZERO;
                        if (recordAddReq.getTotalAmount() != null) {
                            totalAmount = recordAddReq.getTotalAmount();
                        }
                        // 设置实付金额和应缴金额
                        newRecord.setPaymentAmount(paymentAmount);
                        newRecord.setTotalAmount(totalAmount);

                        // 计算应退金额(实付金额 - 应缴金额)
                        newRecord.setNeedBackAmount(paymentAmount.subtract(totalAmount));

                        // 设置是否已退
                        newRecord.setIsBack(false); // 默认未退

                        // 设置备注
                        if (isNullOrEmpty(recordAddReq.getDescription())) {
                            newRecord.setDescription(recordAddReq.getDescription());
                        }

                        // 保存记录
                        this.save(newRecord);

                        break;
                }

                // 3.5 提交事务
                platformTransactionManager.commit(status);
            } catch (Exception e) {
                e.printStackTrace();
                // 捕捉到异常回滚事务
                platformTransactionManager.rollback(status);
            } finally {
                if (status.isNewTransaction() && !status.isCompleted()) {
                    platformTransactionManager.commit(status);
                }
            }
        }

        // 4. 更新任务状态为已结束
        smsImportTask.setStatus(taskStatus);
        smsImportTaskMapper.updateById(smsImportTask);

        return null;
    }

    @Override
    @Async
    public Future<ResponseResult> feesRecordBatchExport(FeesRecordBatchExportReq req, HttpServletResponse response) {
        // 1. 校验参数
        if (isNullOrEmpty(req.getPlanId())) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        // 2. 构造查询条件并获取导出数据
        LambdaQueryWrapper<SmsWnsBookFeesPlanFeesRecord> queryWrapper = new LambdaQueryWrapper<SmsWnsBookFeesPlanFeesRecord>()
                .eq(SmsWnsBookFeesPlanFeesRecord::getPlanId, req.getPlanId())
                .orderByDesc(SmsWnsBookFeesPlanFeesRecord::getCreateTime);

        // 模糊查询字符串
        if (!isNullOrEmpty(req.getSearchStr())) {
            List<String> stuIdList = orgUserStuUtil.getStuIdListBySearchStr(req.getSearchStr());
            queryWrapper.in(SmsWnsBookFeesPlanFeesRecord::getStuId, stuIdList.isEmpty() ? Collections.singletonList("") : stuIdList);
        }

        // 是否已退
        if (req.getIsBack() != null) {
            queryWrapper.eq(SmsWnsBookFeesPlanFeesRecord::getIsBack, req.getIsBack());
        }

        // 获取导出数据
        List<SmsWnsBookFeesPlanFeesRecord> recordList = this.list(queryWrapper);

        try {
            // 3. 导出数据
            // 声明一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            // 获取sheet页数
            double sheetNum = Math.ceil((double) recordList.size() / PER_SHEET_NUM);
            for (int k = 0; k < sheetNum; k++) {
                // 生成一个 sheet页,设置 sheet页 名称为 "学生费用导出表"
                HSSFSheet sheet = workbook.createSheet("学生费用导出表" + (k + 1));
                // 设置表格列宽度为 12
                sheet.setDefaultColumnWidth(12);

                // 设置单元格的显示样式
                HSSFCellStyle cellStyle = workbook.createCellStyle();
                cellStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
                cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                // 设置单元格字体
                HSSFFont font = workbook.createFont();
                font.setFontHeightInPoints((short) 10); // 字号
                font.setBold(true); // 加粗
                cellStyle.setFont(font);

                // 3.1 设置第一行数据
                // 创建第一行表头
                HSSFRow headRow = sheet.createRow(0);
                int fixColumnNum = 15; // 固定列数
                int columnNum = fixColumnNum; // 列数
                for (int i = 0; i < columnNum; i++) {
                    // 创建一个单元格
                    HSSFCell cell = headRow.createCell(i);
                    cell.setCellStyle(cellStyle);

                    String columnName = "";
                    switch (i) {
                        case 0:
                            columnName = "序号";
                            break;
                        case 1:
                            columnName = "学号";
                            break;
                        case 2:
                            columnName = "学籍状态";
                            break;
                        case 3:
                            columnName = "姓名";
                            break;
                        case 4:
                            columnName = "性别";
                            break;
                        case 5:
                            columnName = "身份证号";
                            break;
                        case 6:
                            columnName = "学院";
                            break;
                        case 7:
                            columnName = "专业";
                            break;
                        case 8:
                            columnName = "年级";
                            break;
                        case 9:
                            columnName = "班级";
                            break;
                        case 10:
                            columnName = "辅导员";
                            break;
                        case 11:
                            columnName = "缴费计划名";
                            break;
                        case 12:
                            columnName = "实付金额";
                            break;
                        case 13:
                            columnName = "应缴金额";
                            break;
                        case 14:
                            columnName = "应退金额(负数代表此项欠缴)";
                            break;
                        default:
                            columnName = "";
                    }

                    // 创建一个内容对象
                    HSSFRichTextString text = new HSSFRichTextString(columnName);
                    // 将内容对象的文字内容写入到单元格中
                    cell.setCellValue(text);
                }

                // 设置内容
                int range = SmsSignUpCommonConstant.PER_SHEET_NUM;
                // 如果是最后一个 sheet 页, 修改 range 值
                if (k + 1 == sheetNum) {
                    range = recordList.size() - SmsSignUpCommonConstant.PER_SHEET_NUM * k;
                }
                // 3.2 设置其他行数据
                for (int i = 0; i < range; i++) {
                    // 获取每条数据并设置
                    SmsWnsBookFeesPlanFeesRecord record = recordList.get(PER_SHEET_NUM * k + i);

                    // 获取计划信息
                    SmsWnsBookFeesPlan plan = smsWnsBookFeesPlanMapper.selectById(record.getPlanId());

                    // 获取学生数据
                    SmsStudentInfo studentInfo = smsStudentInfoMapper.selectById(record.getStuId());
                    if (studentInfo == null) {
                        continue;
                    }

                    // 设置数据
                    // 创建一行
                    HSSFRow row = sheet.createRow(i + 1);
                    // 序号
                    row.createCell(0).setCellValue(new HSSFRichTextString(String.valueOf(i + 1)));
                    // 设置除序号外其他数据
                    for (int j = 1; j < columnNum; j++) {
                        String data = "";
                        switch (j) {
                            case 1: // 学号
                                data = studentInfo.getStuNo();
                                break;
                            case 2: // 学籍状态
                                switch (studentInfo.getStuStatus()) {
                                    case "0":
                                        data = "异常";
                                        break;
                                    case "1":
                                        data = "正常";
                                        break;
                                    case "2":
                                        data = "休学";
                                        break;
                                    case "3":
                                        data = "退学";
                                        break;
                                    case "4":
                                        data = "新生入伍";
                                        break;
                                    case "5":
                                        data = "在校入伍";
                                        break;
                                    default:
                                        data = "未知";
                                        break;
                                }
                                break;
                            case 3: // 姓名
                                data = studentInfo.getStuName();
                                break;
                            case 4: // 性别
                                data = studentInfo.getStuSex();
                                break;
                            case 5: // 身份证号
                                data = studentInfo.getStuIdCard();
                                break;
                            case 6: // 学院
                                data = studentInfo.getStuCollege();
                                break;
                            case 7: // 专业
                                data = studentInfo.getStuMajor();
                                break;
                            case 8: // 年级
                                data = studentInfo.getStuGrade();
                                break;
                            case 9: // 班级
                                data = studentInfo.getStuClass();
                                break;
                            case 10: // 辅导员
                                List<SmsUser> assistantList = assistantUtil.getAssistantsByStuId(studentInfo.getId());
                                if (assistantList != null && !assistantList.isEmpty()) {
                                    data = assistantList.get(0).getRealName();
                                } else {
                                    data = "";
                                }
                                break;
                            case 11: // 缴费计划名
                                data = plan == null ? "" : plan.getName();
                                break;
                            case 12: // 实付金额
                                data = record.getPaymentAmount().toString();
                                break;
                            case 13: // 应缴金额
                                data = record.getTotalAmount().toString();
                                break;
                            case 14: // 应退金额(负数代表此项欠缴)
                                data = record.getNeedBackAmount().toString();
                                break;
                            default:
                                data = "";
                        }
                        row.createCell(j).setCellValue(new HSSFRichTextString(data));
                    }
                }
            }

            // 设置 response
            // response.reset();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("学生费用导出表.xlsx", "utf-8"));
            response.setCharacterEncoding("utf-8");
            response.setHeader("file-type", "download");
            response.setHeader("file-name", URLEncoder.encode("学生费用导出表.xlsx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
            // 刷新缓冲
            response.flushBuffer();
            // workbook将Excel写入到response的输出流中，供页面下载
            OutputStream os = response.getOutputStream();
            workbook.write(os);
            workbook.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        return null;
    }

    /**
     * 创建错误记录
     *
     * @param no     学号
     * @param name   姓名
     * @param taskId 任务id
     * @param reason 错误原因
     * @param row    错误行数
     */
    private void createImportTaskDetail(String no, String name, String taskId, String reason, String row) {
        SmsImportTaskDetail smsImportTaskDetail = new SmsImportTaskDetail();
        smsImportTaskDetail.setTaskId(taskId); // 任务id
        smsImportTaskDetail.setFailReason(reason); // 错误原因
        smsImportTaskDetail.setFailName(name); // 姓名
        smsImportTaskDetail.setFailNo(no); // 学号
        smsImportTaskDetail.setFailRow(row); // 错误行数
        smsImportTaskDetailMapper.insert(smsImportTaskDetail);
    }
}
